﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Media3D;
using Perspective.Wpf.Controls;
using Perspective.Core.Wpf;
using System.Threading;
using System.Windows.Threading;
using System.Diagnostics;
using System.Windows.Media.Animation;
using System.Threading.Tasks;

namespace Wpf3dCollaborative
{
    /// <summary>
    /// Logique d'interaction pour SalleReunio.xaml
    /// Cette classe gére la représentation 3d d'une salle de réunion
    /// </summary>
    /// 

    public partial class SalleReunion : ModelVisual3D
    {

        public bool IsCaroussel = false;

        public ModelVisual3D model = new ModelVisual3D();


        /* Transformation du modéle global */
        public Transformer3D Transformer = new Transformer3D();

    
      

        public SalleReunion()
        {
            InitializeComponent();

            Init();
         
            Children.Add(model);
       
        }

        /* Méthode pour la démo */
        public void Demo()
        {
            string Dir = "D:/Users/dfi/Videos/";
            ((Cam)model.Children[0]).TypeCamera = Cam.TypeCam.WEBCAM;

            ((Cam)model.Children[1]).Source = Dir+"monsterMet.mpg";
            ((Cam)model.Children[1]).TypeCamera = Cam.TypeCam.VIDEO;
                     

            ((Cam)model.Children[2]).Source = Dir+"bn.mpg";
            ((Cam)model.Children[2]).TypeCamera = Cam.TypeCam.VIDEO;


            ((Cam)model.Children[3]).Source = Dir + "monsterMet.mpg";
            ((Cam)model.Children[3]).TypeCamera = Cam.TypeCam.VIDEO;


            ((Cam)model.Children[4]).Source = Dir + "bn.mpg";
            ((Cam)model.Children[4]).TypeCamera = Cam.TypeCam.VIDEO;


            ((Cam)model.Children[5]).Source = Dir + "up2.avi";
            ((Cam)model.Children[5]).TypeCamera = Cam.TypeCam.VIDEO;


            ((Cam)model.Children[6]).Source = Dir + "mtv.avi";
            ((Cam)model.Children[6]).TypeCamera = Cam.TypeCam.VIDEO;

            ((Cam)model.Children[7]).Source = Dir + "chuckBerry.mpg";
            ((Cam)model.Children[7]).TypeCamera = Cam.TypeCam.VIDEO;

            ((Cam)model.Children[8]).Source = Dir + "rayvauga.mpg";
            ((Cam)model.Children[8]).TypeCamera = Cam.TypeCam.VIDEO;

            ((Cam)model.Children[9]).Source = Dir + "up.avi";
            ((Cam)model.Children[9]).TypeCamera = Cam.TypeCam.VIDEO;






            ((Cam)model.Children[10]).Source = Dir + "bn.mpg";
            ((Cam)model.Children[10]).TypeCamera = Cam.TypeCam.VIDEO;


            ((Cam)model.Children[11]).Source = Dir + "rayvauga.mpg";
            ((Cam)model.Children[11]).TypeCamera = Cam.TypeCam.VIDEO;


            ((Cam)model.Children[12]).Source = Dir + "mtv.avi";
            ((Cam)model.Children[12]).TypeCamera = Cam.TypeCam.VIDEO;

            ((Cam)model.Children[13]).Source = Dir + "chuckBerry.mpg";
            ((Cam)model.Children[13]).TypeCamera = Cam.TypeCam.VIDEO;

            ((Cam)model.Children[14]).Source = Dir + "johnny_hallyday_parc_des_princes_2003.avi";
            ((Cam)model.Children[14]).TypeCamera = Cam.TypeCam.VIDEO;
            
           

        }

        public void AjouterCoeur()
        {

            Coeur coeur = new Coeur();
            coeur.Transformer.Deplacer(0.5f, 1.2f, 190.0f);
            coeur.Transformer.Redimensionner(0.01f, 0.01f, 0.01f, false);
            Children.Add(coeur);
        }
        public void AjouterSquelette()
        {

            
     
           ContainerUIElement3D tmp = new ContainerUIElement3D();


            Squelette sk = new Squelette(tmp);
            tmp.Children.Add(sk);
        

            tmp.MouseLeftButtonUp += sk.Square3D_MouseLeftButtonUp;
            tmp.MouseMove += sk.Square3D_MouseMove;

            tmp.MouseLeftButtonDown += sk.Square3D_MouseLeftButtonDown;
            tmp.LostMouseCapture += sk.Square3D_LostMouseCapture;
            tmp.PreviewTextInput += sk.Square3D_PreviewTextInput;

            tmp.MouseWheel += sk.Square3D_MouseWheel;
                    

         
  
          App.windows.mainViewport.Children.Add(tmp);
        }

       


        public void AjouterCam()
        {
            // TODO : ne pas supprimer le squelette
           
            if (model.Children.Count < 40)
            {
              
                Cam tmp2 = new Cam();
               
                tmp2.Id = "Cam: "+ model.Children.Count.ToString();
                tmp2.TypeCamera = Wpf3dCollaborative.Cam.TypeCam.IPCAM;

             
                model.Children.Add(tmp2);
                if (IsCaroussel)
                {
                   ClearAllTransforms();
                   RecalculateCaroussel();
                }
                else
                {
                   ClearAllTransforms();
                   RecalculateGrille();
                }
                Children.Clear();
                Children.Add(model);
                
            }
            else
            {
                MessageBox.Show(" Vous ne pouvez avoir plus de 40 objets vidéos");
            }
        }
         

        public void Init()

        {
            float y =0;
            float cpt = 0;
            double angle = 0;
            double radius = 0;
            for (int i = 0; i < 20; i++)
            {

         //int index = model.Children.Count;
                Cam tmp = new Cam();
                model.Children.Add(tmp);
                tmp.Id = "Cam: " +  i.ToString();

               
                    tmp.TypeCamera = Wpf3dCollaborative.Cam.TypeCam.UNCONFIGURED;
                
                if (IsCaroussel)
                {
                    int nbElement = model.Children.Count;
                    if (model.Children.Count == 0)
                        return;

                    angle = 360.0 / nbElement;
                    radius = CalculateRadius();

                    tmp.Transforms.TranformCaroussel(i, angle, radius, nbElement);


                }
                else
                {
                    cpt += 1.6f;
                    switch (i)
                    {
                        case 0: cpt = 0; y = 0.0f; break;
                        case 5: cpt = 0; y = 1.6f; break;
                        case 10: cpt = 0; y = 3.2f; ; break;
                        case 15: cpt = 0; y = 4.8f; ; break;
                        case 20: cpt = 0; y = 6.4f; ; break;
                        case 25: cpt = 0; y = 8.0f; ; break;
                        case 30: cpt = 0; y = 9.6f; ; break;
                        case 35: cpt = 0; y = 11.2f; ; break;
                        case 40: cpt = 0; y = 12.8f; ; break;
                        case 45: cpt = 0; y = 15.4f; ; break;
                        case 50: cpt = 0; y = 17.0f; ; break;
                 

                    }


                    tmp.Transforms.Deplacer(cpt, y, 0.0f);
                }
                tmp = null;
            }
            if (IsCaroussel)
            {
                Transformer.tr.OffsetZ = 90;

            }
            model.Transform = Transformer.GlobalTransform;
        }


        public void RecalculateGrille()
        {
            float cpt = 0, y = 0; 
            for (int i = 0; i < model.Children.Count; i++)
            {
                cpt += 1.6f;
                switch (i)
                {
                    case 0: cpt = 0; y = 0.0f; break;
                    case 5: cpt = 0; y = 1.6f; break;
                    case 10: cpt = 0; y = 3.2f; ; break;
                    case 15: cpt = 0; y = 4.8f; ; break;
                    case 20: cpt = 0; y = 6.4f; ; break;
                    case 25: cpt = 0; y = 8.0f; ; break;
                    case 30: cpt = 0; y = 9.6f; ; break;
                    case 35: cpt = 0; y = 11.2f; ; break;
                    case 40: cpt = 0; y = 12.8f; ; break;
                    case 45: cpt = 0; y = 15.4f; ; break;
                    case 50: cpt = 0; y = 17.0f; ; break;

                }
                ((Cam)model.Children[i]).IsFullScreen = false;
                if (  ((Cam)model.Children[i]).IsWideCam){
                ((Cam)model.Children[i]).SetWideScreenCam();
                ((Cam)model.Children[i]).SetWideScreenCam();
                }
                ((Cam)model.Children[i]).Transforms.Deplacer(cpt, y, 0.0f);
                
            }
           // model.Transform = GlobalTransform;
        }


        /* 
         * Méthodes propres au caroussel      
         */

        /* Permet de réorganiser les éléments en caroussel */
        public void RecalculateCaroussel()
        {
             IsCaroussel = false;
            int nbElement = model.Children.Count;
            if (nbElement == 0)
                return;

            double angle = 360.0 / nbElement;
            double radius = CalculateRadius();
            for (int i = 0; i < nbElement; ++i)
            {

                ((Cam)model.Children[i]).IsFullScreen = false;
                if (((Cam)model.Children[i]).IsWideCam)
                {
                    ((Cam)model.Children[i]).IsWideCam = false;
                    ((Cam)model.Children[i]).SetWideScreenCam();
                }
                ((Cam)model.Children[i]).Transforms.TranformCaroussel(i, angle, radius, nbElement);
              

            }
            Transformer.tr.OffsetZ = 90;
           
        }

        public void RecalculateCaroussel2()
        {
            IsCaroussel = false;
            int nbElement = model.Children.Count;
            if (nbElement == 0)
                return;

            double angle = 360.0 / nbElement;
            double radius = CalculateRadius();
            for (int i = 0; i < nbElement; ++i)
            {

                ((Cam)model.Children[i]).IsFullScreen = false;
                if (((Cam)model.Children[i]).IsWideCam)
                {
                    ((Cam)model.Children[i]).IsWideCam = false;
                    ((Cam)model.Children[i]).SetWideScreenCam();
                }
                ((Cam)model.Children[i]).Transforms.TranformCaroussel2(i, angle, radius, nbElement);


            }
            Transformer.tr.OffsetZ = 90;

        }

        private static double DegreesToRadians(double degrees)
        {
            return (degrees / 180.0) * Math.PI;
        }


        private double CalculateRadius()
        {
            int nbElement = model.Children.Count;
            double splitAngle = 360.0 / nbElement;
            switch (nbElement)
            {
                case 1: return 0.0;
                case 2: return 0.25;
                default:
                    return 1.0 / Math.Abs(Math.Sin(DegreesToRadians(splitAngle)));
            }
        }


   

        public void ClearTransforms()
        {
            Transformer.ClearTransforms();
            Transform = Transformer.GlobalTransform;

        }
        public void ClearAllTransforms()
        {
            ClearTransforms();
           

            for (int i = 0; i < model.Children.Count; ++i)
            {
                if (model.Children[i] is Cam)
                {

                    ((Cam)model.Children[i]).Transforms.ClearTransforms();

                    ((Cam)model.Children[i]).Transform= ((Cam)model.Children[i]).Transforms.GlobalTransform;
                    ((Cam)model.Children[i]).IsFullScreen = false;

                }
            }
        }

        public void Dispose()
        {
            for (int i = 0; i < model.Children.Count; ++i)
            {
                if (model.Children[i] is Cam)
                {
                   ((Cam)model.Children[i]).Dispose();

                }
                else
                {
                    if (model.Children[i] is Coeur)
                    {
                        // ((Objet3D)a.Children[i]) = null;
                    }
                    if (model.Children[i] is Squelette)
                    {
                        // ((Objet3D)a.Children[i]) = null;
                    }
                }


            }
            model.Children.Clear();
   
        }
    }
}
